import json

from home.models import Image, ImageAssignments
from django.db.models import Min, Max
from django.http import HttpResponse
from annotate import getTagIdAndNameOfImage
from django.db import connection,transaction
from accounts.models import User 

def isImageListEmpty(username):
    currUser       = User.objects.get(username=username)
    if isUserReviewer(username) == 1:
        assignedImages = ImageAssignments.objects.filter(user=currUser)
        if len(assignedImages) ==  0:
            return False
        else:
            return True
    assignedImages = ImageAssignments.objects.filter(user=currUser)

    for assignedImage in assignedImages:
        if not assignedImage.image.is_tagged:
            return False
    else:
        return True

def getFirstImageFigureID(username):
    currUser = User.objects.get(username=username)
    if isUserReviewer(username):
        assignedImages = ImageAssignments.objects.filter(reviewer=currUser).order_by('image')
        return assignedImages[0].image.id
    else:
        assignedImages = ImageAssignments.objects.filter(user=currUser).order_by('image')
    for assignedImage in assignedImages:
        if not assignedImage.image.is_tagged:
            return assignedImage.image.id

    return -1

def getImage(username, figureID, offset):
    result = dict()
    nextFigureID = figureID
    if offset != 0:
        nextFigureID = getNextImageID(username, figureID, offset)
    if nextFigureID == -1:
        result = {
            'isSuccessful': False
        }
    else:
        image = Image.objects.get(id=nextFigureID)
        figureID = image.id
        figureLegend = image.legend
        figureTitle = image.title
        figureFilePath = image.image_file_location
        tags = getTagIdAndNameOfImage(figureID, username)
        figureUrl = image.doi_link
        
        result = {
            'isSuccessful': True,
            'isLegendEmpty': True if (figureLegend == None or len(figureLegend) == 0) else False,
            'isTitleEmpty': True if (figureTitle == None or len(figureTitle) == 0) else False,
            'isImageExists': False if (figureFilePath == None or len(figureFilePath) == 0) else True,
            'figureID': figureID,
            'figureLegend': figureLegend,
            'figureTitle': figureTitle,
            'figureFilePath': figureFilePath,
            'figureUrl': figureUrl,
            'tags': tags,
        }
    return HttpResponse(json.dumps(result), content_type="application/json")

def isUserReviewer(username):
    return 1 if User.objects.get(username=username).isReviewer else 0
def getNewReivewerFigureID(images, currFigureID, offset):
    if len(images) == 0:
        return -1
    currIndex = 0
    imageLen = len(images)
    for index in range(len(images)):
        if currFigureID == images[index]:
            currIndex = index
    print 'currIndex:'
    print currIndex
    nextIndexInList = currIndex + offset
    print 'offset:',
    print offset
    print 'next:',
    print nextIndexInList
    if  imageLen == 1:
        nextIndexInList = 0
    elif nextIndexInList < 0:
        nextIndexInList = imageLen - abs(nextIndexInList)
    elif nextIndexInList >= imageLen:
        nextIndexInList = nextIndexInList - imageLen
    return images[nextIndexInList]


def getNextImageID(username, figureID, offset):
    image = Image.objects.get(id=figureID)
    currUser = User.objects.get(username=username)
    if isUserReviewer(username) == 1:
        assignedImages = ImageAssignments.objects.filter(reviewer=currUser).order_by('image').values_list("image_id", flat=True)
        return getNewReivewerFigureID(assignedImages, figureID, offset)
    else:
        assignedImages = ImageAssignments.objects.filter(user=currUser).order_by('image')
    untaggedImageIDs = list()
    currentIndexInList = 0

    # Accurate find
    if not image.is_tagged:
        for assignedImage in assignedImages:
            if assignedImage.image.is_tagged:
                continue
            untaggedImageIDs.append(int(assignedImage.image.id))
            if assignedImage.image.id == figureID:
                currentIndexInList = len(untaggedImageIDs) - 1
    # Last smaller than current number
    else:
        for assignedImage in assignedImages:
            if assignedImage.image.id == figureID:
                currentIndexInList = len(untaggedImageIDs) - 1
            if assignedImage.image.is_tagged:
                continue
            untaggedImageIDs.append(int(assignedImage.image.id))
           
    untaggedImageIDLength = len(untaggedImageIDs)

    if untaggedImageIDLength == 0:
        return -1

    # If image is tagged, than the index may be smaller than 0
    # So we need to locate the accurate index of the last number smaller than current number
    if image.is_tagged:
        if currentIndexInList < 0:
            currentIndexInList = currentIndexInList + untaggedImageIDLength

    nextIndexInList = currentIndexInList + offset
    if untaggedImageIDLength == 1:
        nextIndexInList = 0
    elif nextIndexInList < 0:
        nextIndexInList = untaggedImageIDLength - abs(nextIndexInList)
    elif nextIndexInList >= untaggedImageIDLength:
        nextIndexInList = nextIndexInList - untaggedImageIDLength

    nextFigureID = untaggedImageIDs[nextIndexInList]

    return nextFigureID

def getUnassignedImages(isReviewer):
    cursor = connection.cursor()
    if not isReviewer:
        cursor.execute("select mitagger_images.id from mitagger_images where mitagger_images.id not in (select mitagger_image_assignments.image_id from mitagger_image_assignments where user_id is not null) and is_tagged=0")
    else:
        cursor.execute("select mitagger_images.id from mitagger_images where mitagger_images.id not in (select mitagger_image_assignments.image_id from mitagger_image_assignments where reviewer is not null) and is_tagged=1;")
    return cursor.fetchall()

def getAssignedImages(username):
    if isUserReviewer(username) != 1:
        res = ImageAssignments.objects.filter(user_id=username, image__is_tagged=0)
    else:
        res = ImageAssignments.objects.filter(reviewer_id=username, image_is_tagged=0)
    return res


def assignImage(username, imageCount):
    isSuccessful = True
    errorMessage = str()
    unassignedImages = getUnassignedImages(False)
    if len(unassignedImages) < imageCount:
        isSuccessful = False
        errorMessage = "No enough images"
    else:
        userObject = User.objects.get(username=username)
        for index in range(imageCount):
            unassignedImage = Image.objects.get(id=unassignedImages[index][0])
            newAssignment = ImageAssignments(image=unassignedImage, user=userObject)
            try:
                ImageAssignments.objects.get(image=unassignedImage, user=userObject)
            except:
                newAssignment.save()
    results = {
        'isSuccessful': isSuccessful,
        'errorMessage': errorMessage
    }
    return results
def assignReviewerImages(username, imageCount):
    isSuccessful = True
    errorMessage = str()
    unassignedImages = getUnassignedImages(True)
    if len(unassignedImages) < imageCount:
        isSuccessful = False
        errorMessage = "No enough image."
    else:
        userObject = User.objects.get(username=username)
        for index in range(imageCount):
            unassignedImage = Image.objects.get(id=unassignedImages[index][0])
            newAssignment = ImageAssignments(image=unassignedImage, reviewer=userObject)
            try:
                ImageAssignments.objects.get(image=unassignedImage, reviewer=userObject)
            except:
                newAssignment.save()
    results = {
    'isSuccessful': isSuccessful,
    'errorMessage': errorMessage,
    }
    return results

def getAllAssignedImageCount(isReviewer):
    cursor = connection.cursor()
    if not isReviewer:
        cursor.execute("select mitagger_images.id from mitagger_images where mitagger_images.id in (select mitagger_image_assignments.image_id from mitagger_image_assignments where user_id is not null) and is_tagged=0")
    else:
        cursor.execute("select mitagger_images.id from mitagger_images where mitagger_images.id in (select mitagger_image_assignments.image_id from mitagger_image_assignments where reviewer is not null) and is_tagged=1;")
    return len(cursor.fetchall())
    result = 0
    try:
        assignImages = ImageAssignments.objects.filter(user__isnull=False)
        result = len(assignImages)
    except:
        pass
    return result

def getTotalImageCount():
    result = 0
    try:
        result = len(Image.objects.filter(is_tagged=False))
    except:
        pass
    return result

def getAssignedImageCount(username):
    result = 0
    try:
        userObject = User.objects.get(username=username)
        if isUserReviewer(username) == 1:
            assignedImages = ImageAssignments.objects.filter(reviewer=userObject)
        else:
            assignedImages = ImageAssignments.objects.filter(user=userObject)
        result = len(assignedImages)
    except:
        result = 0
    return result

def getTaggedImageCount(username):
    cursor = connection.cursor()
    if isUserReviewer(username) == 1:
        cursor.execute("select mitagger_images.id from mitagger_images left outer join mitagger_image_assignments on mitagger_images.id=mitagger_image_assignments.image_id where reviewer='" + username + "';")
    else:
        cursor.execute("select mitagger_images.id from mitagger_images left outer join mitagger_image_assignments on mitagger_images.id=mitagger_image_assignments.image_id where is_tagged=1 and user_id='" + username + "';")
    return len(cursor.fetchall())

def getRemainImageCount(username):
    cursor = connection.cursor()
    if isUserReviewer(username) == 1:
        cursor.execute("select mitagger_images.id from mitagger_images left outer join mitagger_image_assignments on mitagger_images.id=mitagger_image_assignments.image_id where reviewer='" + username + "';")
    else:
        cursor.execute("select mitagger_images.id from mitagger_images left outer join mitagger_image_assignments on mitagger_images.id=mitagger_image_assignments.image_id where is_tagged=0 and user_id='" + username + "';")
    return len(cursor.fetchall())

def withdrawImage(username, count):
    assign_list = getAssignedImages(username)
    print len(assign_list)
    if count > len(assign_list):
        return False
    for i in range(count):
        try:
            assign_list[i].delete()
        except:
            pass
    return True


